package bb.lanxing.mvp.presetner;

import android.graphics.Bitmap;
import android.text.TextUtils;
import android.util.SparseArray;

import java.io.File;
import java.util.Arrays;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import bb.lanxing.App;
import bb.lanxing.model.database.PostQueue;
import bb.lanxing.mvp.model.PostQueueModelImpl;
import bb.lanxing.mvp.presetner.i.IPostQueuePresenter;
import bb.lanxing.mvp.view.IPostQueueView;
import bb.lanxing.util.Enums;
import bb.lanxing.util.AppFileUtils;
import bb.lanxing.util.ImageUtil;
import rx.Observable;
import rx.Subscriber;
import rx.schedulers.Schedulers;

public class PostQueuePresenterImpl implements IPostQueuePresenter {
	private final IPostQueueView postQueueView;
	private final Comparator<File> ImageFileCompare = (lhs, rhs) -> {
		String replace = lhs.getName().replace("_cache", "");
		String replace2 = rhs.getName().replace("_cache", "");
		if (replace.matches("[0-9]*") && replace2.matches("[0-9]*")) {
			int intValue = Integer.parseInt(replace);
			int intValue2 = Integer.parseInt(replace2);
			if (intValue > intValue2) {
				return 1;
			}
			return intValue < intValue2 ? -1 : 0;
		}
		return 0;
	};
	private final PostQueueModelImpl postQueueModel = new PostQueueModelImpl();
	private final SparseArray<List<PostQueue>> taskQueue = new SparseArray<>();
	private int taskState = 0;

	public PostQueuePresenterImpl(IPostQueueView postQueueView) {
		this.postQueueView = postQueueView;
	}

	@Override
	public void resetSendingState() {
		this.postQueueModel.resetState(PostQueue.STATE_SENDING, PostQueue.STATE_FAILED);
	}

	@Override
	public void sendPostQueue() {
		for (PostQueue postQueue : this.postQueueModel.getNeedSendList()) {
			addToTaskQueue(postQueue);
		}
		for (int i = 0; i < this.taskQueue.size(); i++) {
			int keyAt = this.taskQueue.keyAt(i);
			List<PostQueue> list = this.taskQueue.get(keyAt);
			if (list != null && !list.isEmpty() && (keyAt & this.taskState) == 0) {
				if (App.networkState == Enums.NetworkState.wifi) {
					sendPost(list.remove(0));
				} else if (App.networkState == Enums.NetworkState.mobile) {
					for (PostQueue postQueue2 : list) {
						postQueue2.setRetryTimes(2);
						this.postQueueView.onSendFailed(postQueue2);
					}
				}
			}
		}
	}

	private void addToTaskQueue(PostQueue data) {
		List<PostQueue> list = this.taskQueue.get(data.getType());
		if (list == null) {
			list = new LinkedList<>();
			this.taskQueue.put(data.getType(), list);
		}
		if (list.contains(data)) {
			return;
		}
		list.add(data);
	}

	@Override
	public void sendPost(final PostQueue data) {
		sendPostInternal(data, true, true);
	}

	@Override
	public void deletePost(PostQueue data) {
		File cacheDir = getCacheDir(data);
		if (cacheDir != null) {
			for (File file : cacheDir.listFiles()) {
				if (file.exists()) {
					file.delete();
				}
			}
			if (cacheDir.exists()) {
				cacheDir.delete();
			}
		}
		if (data.getId() != 0) {
			data.delete();
		}
		List<PostQueue> list = this.taskQueue.get(data.getType());
		if (list != null) {
			list.remove(data);
			if (list.isEmpty()) {
				this.taskQueue.remove(data.getType());
			}
		}
	}

	public void sendPostInternal(final PostQueue data, boolean checkImage, boolean checkTask) {
		if (checkTask && (this.taskState & data.getType()) != 0) {
			addToTaskQueue(data);
			return;
		}
		if (checkImage) {
			data.setState(PostQueue.STATE_SENDING);
			data.save();
			this.taskState |= data.getType();
			if (sendImageFirst(data)) {
				return;
			}
		}
		int type = data.getType();
		if (type == PostQueue.TYPE_TOPIC) {
			this.postQueueModel.sendTopic(data).subscribe(new PostQueueResultSubscriber(data));
		} else if (type == PostQueue.TYPE_TOPIC_COMMENT) {
			this.postQueueModel.sendTopicComment(data).subscribe(new PostQueueResultSubscriber(data));
		} else if (type == PostQueue.TYPE_CLUB_NOTICE) {
			this.postQueueModel.sendClubNotice(data).subscribe(new PostQueueResultSubscriber(data));
		} else if (type == PostQueue.TYPE_CLUB_COMMENT) {
			this.postQueueModel.sendClubComment(data).subscribe(new PostQueueResultSubscriber(data));
		} else if (type == PostQueue.TYPE_WORKOUT_COMMENT) {
			this.postQueueModel.sendWorkoutComment(data).subscribe(new PostQueueResultSubscriber(data));
		} else if (type == PostQueue.TYPE_LUSHU_COMMENT) {
			this.postQueueModel.sendLushuComment(data).subscribe(new PostQueueResultSubscriber(data));
		} else {
			if (type == PostQueue.TYPE_SHOP_COMMENT) {
				this.postQueueModel.sendShopComment(data).subscribe(new PostQueueResultSubscriber(data));
			}
		}
	}

	private boolean sendImageFirst(final PostQueue data) {
		File[] listFiles;
		final File cacheDir = getCacheDir(data);
		if (cacheDir == null || (listFiles = cacheDir.listFiles()) == null || listFiles.length == 0) {
			return false;
		}
		List<File> asList = Arrays.asList(listFiles);
		asList.sort(this.ImageFileCompare);
		Observable.from(asList).subscribeOn(Schedulers.io()).flatMap(file -> {
			String uploadImage = postQueueModel.uploadImage(file.getAbsolutePath(), data.getType());
			if (!TextUtils.isEmpty(uploadImage)) {
				file.delete();
			}
			return Observable.just(uploadImage);
		}).subscribe(new Subscriber<>() {
			boolean error = false;
			@Override
			public void onCompleted() {
				File[] listFiles2;
				if (this.error) {
					return;
				}
				for (File file : cacheDir.listFiles()) {
					if (file.exists()) {
						file.delete();
					}
				}
				if (cacheDir.exists()) {
					cacheDir.delete();
				}
				sendPostInternal(data, false, false);
			}

			@Override
			public void onError(Throwable e) {
				this.error = true;
				sendFailed(data);
				e.printStackTrace();
			}

			@Override
			public void onNext(String url) {
				if (url == null) {
					throw new IllegalStateException("image upload failed !");
				}
				String images = data.getImages();
				if (!TextUtils.isEmpty(images)) {
					url = images + ";" + url;
				}
				data.setImages(url);
				data.save();
			}
		});
		return true;
	}

	public void sendNext(PostQueue data) {
		data.delete();
		Observable.just(data).delay(500L, TimeUnit.MILLISECONDS).subscribe(postQueueView::onSendSucceed);
		List<PostQueue> list = this.taskQueue.get(data.getType());
		if (list == null || list.isEmpty()) {
			this.taskState = (~data.getType()) & this.taskState;
			return;
		}
		sendPostInternal(list.remove(0), true, false);
	}

	public void sendFailed(PostQueue data) {
		if (data.getRetryTimes() < 2) {
			data.setRetryTimes(data.getRetryTimes() + 1);
			data.save();
			sendPostInternal(data, true, false);
			return;
		}
		data.setState(2);
		data.setRetryTimes(0);
		data.save();
		Observable.just(data).delay(500L, TimeUnit.MILLISECONDS).subscribe(postQueueView::onSendFailed);
	}

	@Override
	public void cacheImage(PostQueue data, List<String> paths) {
		File cacheDir = getCacheDir(data);
		if (cacheDir == null) {
			return;
		}
		File buildTakePhotoDir = ImageUtil.buildTakePhotoDir();
		for (int i = 0; i < paths.size(); i++) {
			File file = new File(paths.get(i));
			if (file.exists()) {
				int type = data.getType();
				if (type == 1 || type == 2 || type == 4 || type == 8 || type == 16 || type == 32 || type == 64) {
					Bitmap canUploadSourceImage = ImageUtil.getCanUploadSourceImage(file.getPath(), true);
					ImageUtil.storeJPGImage(canUploadSourceImage, cacheDir.getAbsolutePath() + File.separator + i + "_cache", 80);
				} else {
					AppFileUtils.copyFile(file, cacheDir, i + "_cache");
				}
				if (buildTakePhotoDir != null && buildTakePhotoDir.equals(file.getParentFile())) {
					file.delete();
				}
			}
		}
	}

	@Override
	public boolean isValid(PostQueue data) {
		return this.postQueueModel.isDataValid(data);
	}

	private File getCacheDir(PostQueue data) {
		String str;
		if (data.getId() == 0) {
			return null;
		}
		File externalCacheDir = App.getContext().getExternalCacheDir();
		int type = data.getType();
		if (type == 1) {
			str = "topic";
		} else if (type == 2) {
			str = "topic_comment";
		} else if (type == 4) {
			str = "club_notice";
		} else if (type == 8) {
			str = "club_comment";
		} else if (type == 16) {
			str = "workout_comment";
		} else if (type == 32) {
			str = "lushu_comment";
		} else if (type != 64) {
			return null;
		} else {
			str = "shop_comment";
		}
		File file = new File(externalCacheDir, str + File.separator + data.getId());
		if (file.exists() || file.mkdirs()) {
			return file;
		}
		return null;
	}

	public class PostQueueResultSubscriber extends Subscriber<Boolean> {
		private final PostQueue data;

		private PostQueueResultSubscriber(PostQueue data) {
			this.data = data;
		}

		@Override
		public void onCompleted() {
		}

		@Override
		public void onError(Throwable e) {
			sendFailed(this.data);
			e.printStackTrace();
		}

		@Override
		public void onNext(Boolean succeed) {
			if (succeed) {
				sendNext(this.data);
			} else {
				sendFailed(this.data);
			}
		}
	}
}
